import { _decorator, Component, EventTouch, Label, Node, Sprite, tween, v3, Vec2, Vec3 } from 'cc';
import { DEBUG } from 'cc/env';
import AssetModule from 'db://cocos-ext/base/AssetModule';
import EventExt from 'db://cocos-ext/base/EventExt';

import Train from '../define/Train';
import { Direction, EVENT_TILE_CLICK, EVENT_TILE_MOVE, UIConfig } from '../define/UIConfig';

const { ccclass, property } = _decorator;

@ccclass('Tile')
export default class Tile extends Component {

    // 图片
    @property(Sprite)
    private readonly sprite: Sprite = null;


    /** 方块的类型 */
    public get type() {
        return this._type;
    }
    private _type: number = -1;

    /** 方块的坐标 */
    public get xy() {
        return this._xy;
    }
    private _xy: Train = new Train(0, 0);


    // test label
    private _label: Label = null;
    private get label(): Label {
        if (!this._label) {
            const node = new Node();
            this._label = node.addComponent(Label);
            this._label.fontSize = 32;
            this.node.addChild(node);
        }
        return this._label;
    }


    protected onLoad() {
        this.node.on(Node.EventType.TOUCH_CANCEL, (e: EventTouch) => {
            const dir: Direction = this.getDirection(e.getStartLocation(), e.getLocation());
            EventExt.emit(EVENT_TILE_MOVE, this.xy.copy(), dir);
        });
        this.node.on(Node.EventType.TOUCH_END, () => {
            EventExt.emit(EVENT_TILE_CLICK, this.xy.copy());
        });
    }

    /**
    * 设置类型
    * @param type 类型
    */
    public setType(type: number) {
        this._type = type;
        const isValid = type >= 0 && type < UIConfig.iconCnt();
        const sp = isValid ? AssetModule.getSpriteFrame(UIConfig.ICON_LIST[type]) : null;
        this.sprite.spriteFrame = sp;
        if (DEBUG) this.label.string = type.toString();
    }

    /**
    * 设置坐标
    * @param x 横坐标
    * @param y 纵坐标
    */
    public setXY(x: number | Train, y?: number) {
        if (!this._xy)
            this._xy = new Train(x, y);
        else
            this._xy.set(x, y);
    }

    /**
    * 显示方块
    */
    public show() {
        tween(this.node)
            .set({ scale: Vec3.ZERO })
            .to(0.075, { scale: v3(1.1, 1.1, 1.1) })
            .to(0.025, { scale: Vec3.ONE })
            .start();
    }

    /**
    * 消失并回收
    */
    public hide() {
        tween(this.node)
            .set({ scale: Vec3.ONE })
            .to(0.1, { scale: Vec3.ZERO })
            .call(() => AssetModule.putPoolNode(this.node))
            .start();
    }

    /**
    * 获取s手指滑动方向
    * @param startPos 开始位置
    * @param endPos 结束位置
    */
    private getDirection(startPos: Vec2, endPos: Vec2): Direction {
        const offsetX = endPos.x - startPos.x; // x 偏移
        const offsetY = endPos.y - startPos.y; // y 偏移

        if (Math.abs(offsetX) < Math.abs(offsetY)) {
            return offsetY > 0 ? Direction.Up : Direction.Down
        } else {
            return offsetX > 0 ? Direction.Right : Direction.Left;
        }
    }
}
